﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Collections;
using DoubleH.Utility.Configuration;
using System.Reflection;
using FCNS.Data;

namespace DoubleH.Utility.Search
{
    /// <summary>
    /// WindowSearch.xaml 的交互逻辑
    /// </summary>
    public partial class WindowSearch : Window
    {
        internal protected enum Flag
        {
            无,
            左括号,
            右括号,
            条件符号,
            栏目,
            移除
        }

        public WindowSearch()
        {
            InitializeComponent();

            InitVar();
            InitEvent();
        }

        ObservableCollection<TempClass> tclass = new ObservableCollection<TempClass>();
        Flag currentFlag = Flag.无;
        MenuItemBinding selectedMenu = null;
        Type tableType = null;

        private void InitVar()
        {
            listBoxResult.ItemsSource = tclass;

            comboBoxField1.DisplayMemberPath = "Header";
            //comboBoxField.SelectedValuePath = "BindingName";

            comboBoxTiaoJian.Items.Add(" 大于 ");
            comboBoxTiaoJian.Items.Add(" 大于等于 ");
            comboBoxTiaoJian.Items.Add(" 等于 ");
            comboBoxTiaoJian.Items.Add(" 小于 ");
            comboBoxTiaoJian.Items.Add(" 小于等于 ");
            comboBoxTiaoJian.Items.Add(" 包含 ");
            comboBoxTiaoJian.Items.Add(" 不包含 ");
            comboBoxTiaoJian.Items.Add(" 开头等于 ");
            comboBoxTiaoJian.Items.Add(" 开头不等于 ");
            comboBoxTiaoJian.Items.Add(" 结尾等于 ");
            comboBoxTiaoJian.Items.Add(" 结尾不等于 ");
        }

        private void InitEvent()
        {
            buttonAdd.Click += (ss, ee) => AddItem();
            buttonDelete.Click += (ss, ee) => RemoveItem();
            buttonAnd.Click += (ss, ee) => AddAnd();
            buttonOr.Click += (ss, ee) => AddOr();
            buttonSearch.Click += (ss, ee) => Search();
            buttonKuoHaoL.Click += (ss, ee) => KuoHaoL();
            buttonKuoHaoR.Click += (ss, ee) => KuoHaoR();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="selectedMenu"></param>
        /// <param name="tableType">要搜索的数据表的类型,为了获取Flag或者Enable</param>
        public void Init(MenuItemBinding selectedMenu, Type tableType)
        {
            Debug.Assert(selectedMenu != null);
            UserUIparams binding = DoubleHConfig.UserConfig.DataGridBinding.Find(f => { return f.TableText == selectedMenu.TableText; });
            Debug.Assert(binding != null);

            this.tableType = tableType;
            this.Title += (" - " + selectedMenu.TableText.ToString());
            comboBoxField1.ItemsSource = binding.Items;
            this.selectedMenu = selectedMenu;
        }

        public IList Items { get; set; }


        private bool CheckFlag(Flag flag)
        {
            bool result = false;
            switch (flag)
            {
                case Flag.左括号://永远是正确的
                    result = (currentFlag == Flag.左括号 || currentFlag == Flag.条件符号 || currentFlag == Flag.无);
                    break;

                case Flag.右括号:
                    result = (currentFlag == Flag.右括号 || currentFlag == Flag.栏目);
                    break;

                case Flag.条件符号:
                    result = (currentFlag == Flag.右括号 || currentFlag == Flag.栏目);
                    break;

                case Flag.栏目:
                    result = (currentFlag == Flag.左括号 || currentFlag == Flag.条件符号 || currentFlag == Flag.无);
                    break;

                case Flag.移除:
                    result = listBoxResult.HasItems;
                    break;

                default:
                    Debug.Assert(false);
                    break;
            }

            if (result)
                currentFlag = flag;

            return result;
        }

        private void KuoHaoL()
        {
            if (!CheckFlag(Flag.左括号))
                return;

            tclass.Add(new TempClass() { TiaoJian = "（", _Flag = Flag.左括号 });
        }

        private void KuoHaoR()
        {
            if (!CheckFlag(Flag.右括号))
                return;

            tclass.Add(new TempClass() { TiaoJian = "）", _Flag = Flag.右括号 });
        }

        private void AddItem()
        {
            if (comboBoxTiaoJian.SelectedItem == null)
                return;

            if (!CheckFlag(Flag.栏目))
                return;

            DataGridColumnHeaderBinding column = (DataGridColumnHeaderBinding)comboBoxField1.SelectedItem;
            TempClass tc = new TempClass();
            tc.Name = column.Header;
            tc.DataColumnName = column.BindingName;
            tc.TiaoJian = comboBoxTiaoJian.Text;
            tc._Flag = Flag.栏目;
            tc.SearchValue = string.IsNullOrEmpty(comboBoxValue.Text) ? "''" : "'" + comboBoxValue.Text + "'";
            tclass.Add(tc);
        }

        private void RemoveItem()
        {
            if (!CheckFlag(Flag.移除))
                return;

            tclass.RemoveAt(tclass.Count - 1);
            if (listBoxResult.HasItems)
                currentFlag = tclass.LastOrDefault()._Flag;
            else
                currentFlag = Flag.无;
        }

        private void AddAnd()
        {
            if (!CheckFlag(Flag.条件符号))
                return;

            tclass.Add(new TempClass() { TiaoJian = "并且", SearchValue = "and", _Flag = Flag.条件符号 });
        }

        private void AddOr()
        {
            if (!CheckFlag(Flag.条件符号))
                return;

            tclass.Add(new TempClass() { TiaoJian = "或者", SearchValue = "or", _Flag = Flag.条件符号 });
        }

        private void Search()
        {
            Assembly assembly = Assembly.LoadFile(DbDefine.baseDir + "FCNS.Data.dll");
            FCNS.Data.Interface.ISearch table = null;
            try
            {
                table = assembly.CreateInstance("FCNS.Data.Table." + selectedMenu.TableName) as FCNS.Data.Interface.ISearch;
                if (table == null)
                {
                    MessageWindow.Show("当前内容不支持高级查询.");
                    Items = null;
                }
                else
                {
                    var vr = table.GetListByWhere(FormatString());
                    //以下操作效率太差了.
                    if (vr == null || vr.Count == 0)
                        return;

                    List<object> result = new List<object>();
                    Type tp = vr[0].GetType();
                    PropertyInfo info = tp.GetProperty("Flag");
                    if (info != null)
                        AddObjectCheckFlagOrEnable(info, vr, result);
                    else
                    {
                        info = tp.GetProperty("Enable");
                        AddObjectCheckFlagOrEnable(info, vr, result);
                    }
                    Items = result;
                }
            }
            catch { MessageWindow.Show(selectedMenu.TableText.ToString() + " 构造函数异常"); }
            this.Close();
        }

        private void AddObjectCheckFlagOrEnable(PropertyInfo info, IList vr, List<object> result)
        {
            if (info == null)
                return;

            if (Enum.GetNames(info.PropertyType).Contains(selectedMenu.TableText.ToString()))
            {
                foreach (object obj in vr)
                {
                    //MessageBox.Show(info.GetValue(obj, null).ToString() + result.Count.ToString() + "  " + vr.Count.ToString());
                    if (info.GetValue(obj, null).ToString() == selectedMenu.TableText.ToString())
                        result.Add(obj);
                }
            }
            else
                foreach (object obj in vr)
                    result.Add(obj);
        }

        private string FormatString()
        {
            TempClass tt = tclass.LastOrDefault();
            if (tt == null)
                return string.Empty;

            Flag fl = tt._Flag;
            while (fl != Flag.栏目 && fl != Flag.右括号)
            {
                tclass.RemoveAt(tclass.Count - 1);
                if (listBoxResult.HasItems)
                    fl = tclass.LastOrDefault()._Flag;
                else
                    break;
            }

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < tclass.Count; i++)
            {
                TempClass tc = tclass[i];
                switch (tc._Flag)
                {
                    case Flag.左括号://永远是正确的
                        sb.Append("( ");
                        break;

                    case Flag.右括号:
                        sb.Append(") ");
                        break;

                    case Flag.条件符号:
                        sb.Append(" " + tc.SearchValue + " ");
                        break;

                    case Flag.栏目:
                        switch (tc.TiaoJian)
                        {
                            case " 大于 ":
                                sb.Append(FormatSql(tc) + " > " + tc.SearchValue);
                                break;
                            case " 大于等于 ":
                                sb.Append(FormatSql(tc) + " >= " + tc.SearchValue);
                                break;
                            case " 等于 ":
                                sb.Append(FormatSql(tc) + " = " + tc.SearchValue);
                                break;
                            case " 小于 ":
                                sb.Append(FormatSql(tc) + " < " + tc.SearchValue);
                                break;
                            case " 小于等于 ":
                                sb.Append(FormatSql(tc) + " <= " + tc.SearchValue);
                                break;
                            case " 包含 ":
                                sb.Append(FormatSql(tc) + " like " + tc.SearchValue.Insert(1, "%").Insert(tc.SearchValue.Length, "%"));
                                break;
                            case " 不包含 ":
                                sb.Append(FormatSql(tc) + " not like " + tc.SearchValue.Insert(1, "%").Insert(tc.SearchValue.Length, "%"));
                                break;
                            case " 开头等于 ":
                                sb.Append(FormatSql(tc) + " like " + tc.SearchValue.Insert(tc.SearchValue.Length - 1, "%"));
                                break;
                            case " 开头不等于 ":
                                sb.Append(FormatSql(tc) + " not like " + tc.SearchValue.Insert(tc.SearchValue.Length - 1, "%"));
                                break;
                            case " 结尾等于 ":
                                sb.Append(FormatSql(tc) + " like " + tc.SearchValue.Insert(1, "%"));
                                break;
                            case " 结尾不等于 ":
                                sb.Append(FormatSql(tc) + " not like " + tc.SearchValue.Insert(1, "%"));
                                break;
                        }
                        break;

                    default:
                        Debug.Assert(false);
                        break;
                }
            }
            int left = tclass.Count(l => l._Flag == Flag.左括号);
            int right = tclass.Count(r => r._Flag == Flag.右括号);
            if (left > right)
            {
                for (int i = 0; i < left - right; i++)
                    sb.Append(")");
            }
            else if (left < right)
            {
                for (int i = 0; i < right - left; i++)
                    sb.Insert(0, "(");
            }

            sb.Insert(0, " where ");

            return sb.ToString();
        }

        private string FormatSql(TempClass tc)
        {
            if (tc.DataColumnName.StartsWith("_"))
                return tc.DataColumnName;
            else
                return selectedMenu.TableName + "." + tc.DataColumnName;
        }



        internal protected class TempClass
        {
            internal protected string Name { get; set; }
            internal protected string DataColumnName { get; set; }
            internal protected Flag _Flag { get; set; }

            internal protected string TiaoJian { get; set; }
            internal protected string SearchValue { get; set; }

            public override string ToString()
            {
                return Name + " " + TiaoJian + " " + SearchValue;
            }
        }
    }
}